#ifndef __VERTEX_H__
#define __VERTEX_H__
#include "math.h"
#pragma once
#define		Real	double

class CVertex
{
public:
    double x, y;

	CVertex (void): x(0), y(0) {}
    CVertex (double xx, double yy)	{ Set(xx, yy);}
	CVertex (const CVertex& src)	{ Set(src.x, src.y) ; }
    ~CVertex (void) {}

	void	Set( double xx, double yy ) { x=xx; y=yy; }
	void	Set( CVertex &vert ) { Set(vert.x, vert.y ) ; }

    double Norm (void) const { return sqrt (x * x + y * y); }
	double SquaredNorm (void) const { return x * x + y * y ; }
    double Normalize (void)
	{ 
		double norm = (double)sqrt (x * x + y * y);
		if (norm > EPS_6)
		{
			double invnorm = 1.0f / norm;
			x *= invnorm;
			y *= invnorm;
			return norm;
		}
		else
			return 0.0f;
	}

	bool IsZero() const
	{
		if(  fabs(x)<EPS_6 && fabs(y)<EPS_6 )
		{
			return true;
		} 
		else 
		{
			return false;
		}

	}

    CVertex& operator= (const CVertex& src)
	{ 
		x = src.x;
		y = src.y;
		return *this;
	}

    CVertex operator+ (const CVertex &other) const
	{ return CVertex (x + other.x, y + other.y); } 

    CVertex operator- (void) const
	{ return CVertex (-x, -y); }

    CVertex operator- (const CVertex &other) const
	{ return CVertex (x - other.x, y - other.y); } 

    CVertex operator* (double k) const         // scale
	{ return CVertex (k * x, k *y); } 

    friend CVertex operator* (double k, const CVertex &a)
	{ return CVertex (k * a.x, k * a.y); }

    CVertex& operator += (const CVertex &other)
	{ 
		x += other.x;
		y += other.y;
		return *this;
	}

    CVertex& operator -= (const CVertex &other)
	{
		x -= other.x;
		y -= other.y;
		return *this;
	}

    CVertex& operator *= (const double k)
	{ 
		x *= k;
		y *= k;
		return *this;
	}
   
    double operator * (const CVertex &other) const  // dot product
	{   return x * other.x + y * other.y; } 

    double operator ^ (const CVertex &other) const  // cross product
	{   return x * other.y - y * other.x; } 

	bool operator == (const CVertex &other) const
	{
		if ( fabs( x - other.x )<EPS_6 && fabs( y - other.y)<EPS_6 )
			return true;
		else 
			return false;
	}

	bool operator != (const CVertex &other) const // test equal, by v-hcke
	{
		if ( fabs( x - other.x )<EPS_6 && fabs( y - other.y)<EPS_6 )
			return false;
		else 
			return true;
	}
}; 


// a looped vector, but not safe for index
template <class T>
class loop_list : public std::vector<T>
{
public:
	T& operator [] (int index)
	{
		int size = (int)this->size();
		while(index >= size)
		{
			index -= size; 
		}
		while(index < 0)
		{
			index += size;
		}
		assert(index >= 0 && index < size);
		return vector<T>::operator [](index);
	}
};


typedef loop_list<CVertex *> vertex_list;

#endif
